﻿using System.Collections.Generic;
using System.Linq;

namespace ntestools
{
    /// <summary>
    /// Содержит вспомогательные методы для сравнения объектов
    /// </summary>
    public static class EqualsHelper
    {
        /// <summary>
        /// Сравнивает перечисления
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumerable1">первое перечисление</param>
        /// <param name="enumerable2">второе перечисление</param>
        /// <returns>true - если все элементы перечисления совпали 1 к 1</returns>
        public static bool AreEquals<T>(IEnumerable<T> enumerable1, IEnumerable<T> enumerable2)
        {
            if (enumerable1.Count() != enumerable2.Count())
            {
                return false;
            }
            IEnumerator<T> enumerator1 = enumerable1.GetEnumerator();
            IEnumerator<T> enumerator2 = enumerable2.GetEnumerator();
            while (enumerator1.MoveNext())
            {
                enumerator2.MoveNext();
                if (!enumerator1.Current.Equals(enumerator2.Current))
                {
                    return false;
                }
            }
            return true;
        }

        public static bool AreEqual(object obj1, object obj2)
        {
            if (obj1 == null && obj2 == null)
            {
                return true;
            }
            if (obj1 == null && obj2 != null
                || obj1 != null && obj2 == null)
            {
                return false;
            }

            foreach (var property in obj1.GetType().GetProperties())
            {

                bool equalProperties = property.PropertyType.IsClass && property.PropertyType != typeof(string)
                    ? AreEqual(property.GetValue(obj1, null), property.GetValue(obj2, null))
                    : property.GetValue(obj1, null).Equals(property.GetValue(obj2, null));
                if (!equalProperties)
                {
                    return false;
                }
            }
            return true;
        }
    }
}
